跳到主要内容

Linux 的定时任务

定时任务的种类

工作调度的种类: at, cron

两种工作调度的方式:

  • 一种是例行性的,就是每隔一定的周期要来办的事项;
  • 一种是突发性的,就是这次做完以后就没有的那一种

Linux 的 at 和 crontab 命令

那么在 Linux 下面如何达到这两个功能呢?那就得使用 at 与 crontab 这两个命令

at :at 是个可以处理仅执行一次就结束调度的指令,不过要执行 at 时, 必须要有 atd 这个服务,atd 服务是独立的服务

crontab :crontab (crontab 命令,它是 cron table 的简写)这个指令所设置的工作将会循环的一直进行下去,可循环的时间为分钟、小时、每周、每月或每年等。crontab 除了可以使用指令执行外,亦可编辑 /etc/crontab 来支持。 至于让 crontab 可以生效的服务则是 crond 这个服务。

仅执行一次的工作调度 at

首先必须要有这个 atd 调度服务

sudo service atd restart # 重新启动 atd 这个服务
sudo service atd enable # 让这个服务开机就自动启动
sudo service atd status # 查阅一下 atd 目前的状态

使用 at 这个指令来产生所要运行的工作,并将这个工作以文本文件的方式写入 /var/spool/at/ 目录内,该工作便能等待 atd 这个服务的取用与执行了。

at 的工作情况其实是这样的:

  1. 先找寻 /etc/at.allow 这个文件,写在这个文件中的使用者才能使用 at ,没有在这个文件中的使用者则不能使用 at (即使没有写在 at.deny 当中);
  2. 如果 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的使用者则不能使用 at ,而没有在这个 at.deny 文件中的使用者,就可以使用 at 咯;

如果两个文件都不存在,那么只有 root 可以使用 at 这个指令。

基本的语法如下:

$ at [-mldv] TIME
选项与参数:
-m :当 at 的工作完成后,即使没有输出讯息,亦以 email 通知使用者该工作已完成。
-l :at -l 相当于 atq,列出目前系统上面的所有该使用者的 at 调度;
-d :at -d 相当于 atrm ,可以取消一个在 at 调度中的工作;
-v :可以使用较明显的时间格式列出 at 调度中的工作列表;
-c :可以列出后面接的该项工作的实际指令内容。

如下使用

使用 Ctrl + D 可以结束输入,结尾处生成一个 <EOT>

在执行前,可以使用 atq 命令检查当前的任务

$ atq
4 Wed Feb 2 21:04:00 2022 a alsritter

不过这些任务会进入一个 at shell 的环境来让使用者下达工作指令,所以这个 echo 命令并不会显示在当前 Shell 上

e.g.

# 5 分钟之后
[root@localhost ~]$ at now + 5 minutes

# 三天后的下午 5 点执行 /bin/ls
[root@localhost ~]$ at 5pm+3 days
at> /bin/ls
at> <EOT>
job 7 at 2020-01-08 17:00

# 明天17点钟,输出时间到指定文件内
[root@localhost ~]$ at 17:20 tomorrow
at> date >/root/2020.log
at> <EOT>
job 8 at 2020-01-06 17:20

# 计划任务设定后,在没有执行之前我们可以用 atq 命令来查看系统没有执行工作任务:
[root@localhost ~]$ atq
8 2020-01-06 17:20 a root
7 2020-01-08 17:00 a root

# 删除已经设置的任务
[root@localhost ~]$ atrm 7
[root@localhost ~]$ atq
8 2020-01-06 17:20 a root

# 显示已经设置的任务内容

[root@localhost ~]$ at -c 8
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0

如果使用 at 命令创建任务后想修改怎么办?利用 atq 与 atrm 把它移除

$ atq
$ atrm (jobnumber)

定时任务 crontab

sudo service cron start     #启动服务
sudo service cron stop #关闭服务
sudo service cron restart #重启服务
sudo service cron reload #重新载入配置
sudo service cron status #查看服务状态

可以限制使用 crontab 的使用者帐号!使用的限制数据有:

  • /etc/cron.allow:将可以使用 crontab 的帐号写入其中,若不在这个文件内的使用者则不可使用 crontab;
  • /etc/cron.deny:将不可以使用 crontab 的帐号写入其中,若未记录到这个文件当中的使用者,就可以使用 crontab 。

当使用者使用 crontab 这个指令来创建工作调度之后,该项工作就会被纪录到 /var/spool/cron/ 里面去了

$ crontab [-u username]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作调度;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑。

crontab -e 进入当前用户的工作表编辑

crontab 的命令构成为 时间+动作,其时间有分、时、日、月、周五种,操作符有

* 取值范围内的所有数字
/ 每过多少个数字
- 从X到Z
,散列数字

e.g.

# 实例1:每1分钟执行一次 myCommand
* * * * * myCommand
# 实例2:每小时的第3和第15分钟执行
3,15 * * * * myCommand
# 实例3:在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * myCommand

这个 crontab -e 是针对使用者的 cron 来设计的,如果是 “系统的例行性任务” 时, 该怎么办呢?只要编辑 /etc/crontab 这个文件就可以啦

$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

这些字段的含义:

  • minute:代表一小时内的第几分,范围 0-59。
  • hour:代表一天中的第几小时,范围 0-23。
  • mday:代表一个月中的第几天,范围 1-31。
  • month:代表一年中第几个月,范围 1-12。
  • wday:代表星期几,范围 0-7 (0及7都是星期天)。
  • who:要使用什么身份执行该指令,当使用 crontab -e 时,不必加此字段。
  • command:所要执行的指令。

检查当前的定时任务

$ crontab -l  # 表示列出所有的定时任务
$ crontab -r # 表示删除用户的定时任务,当执行此命令后,所有用户下面的定时任务会被删除,执行crontab -l后会提示用户:“no crontab for admin”

References

at 命令详解